翻轉電子書系列:Java 程式設計()含物件導向 描述: 回首頁.png 

描述: 粘_4.png翻轉工作室:粘添壽

 

第六章  檔案輸入與輸出運用

6-1 檔案輸入/輸出模式

資訊系統大多需要檔案來儲存資料。當使用者輸入建立資料之後,需將所登錄的資料儲存到檔案內,下次管理資料時再由檔案讀入原來資料,如此才能管理龐大資料量。檔案是資料儲存於磁碟機的空間結構,不同的儲存結構也可能影響到資料存取效率,也需要相對應的存取方法來配合。一般資訊系統的檔案型態可區分為順序檔案與紀錄檔案兩大類,前者大多採用串流存取模式;後者大多採用緩衝器存取技巧。以下分別介紹這兩種檔案型態的特性與宣告產生方式。

6-1-1 順序檔案與串流讀寫

將資料依序寫入、讀出檔案。好像錄製錄音帶一樣,由起頭開始依序寫入磁帶,最後標示一個特殊記號表示結束,讀出時也要從頭開始順序讀取,此種儲存檔格式稱為『順序檔案』(Sequence File)。簡單的說,順序檔案允許資料以連串方式,一點一滴依序寫入磁碟檔案內,也允許一點接一點依序由檔案讀出,吾人則將此存取技巧稱之為『串流』(stream)讀寫。早期順序檔案主要是針對磁帶機的存取方式,但最近網路運用普遍,電腦之間透過網路傳輸資料,大多不喜歡資料傳輸完畢後,再執行下一步驟的處理,大多希望一邊傳輸資料,一邊處理已傳輸部分資料,資料全部傳輸完畢後,也剛好全部處理完畢。譬如,收聽網站上音樂,音樂檔案必須由網站下載到個人電腦上,再由個人電腦撥放該音樂檔案。我們當然希望一邊傳輸音樂檔案,一邊撥放該音樂,全部傳輸完畢後,也剛好收聽完畢,因此就必須利用順序格式讀取音樂檔案,這就是串流的概念。其實,網路上除了音樂檔案之外,無論是視訊、動畫、影像等等檔案也大多如此。也就是說,多媒體檔案大多採用順序檔案格式與串流存取方式,尤其透過網路傳輸也顯得需要。

6-1 串流檔案輸入/輸出物件

順序檔案是利用串流(Stream)方式,連續性的寫入或讀出。產生檔案時必須宣告它成為串流輸入/輸出檔案;另一方面,也必須將寫入檔案的記憶體資料宣告成串流型態。圖 6-1 是將 Employee.data 檔案宣告成串流輸入/輸出檔案,並產生串流輸入/輸出通道。

6-1-2 紀錄檔案與緩衝器讀寫

描述真實環境現象的資料大多有一定的規範,每樣事件大多由一筆資料記載它的屬性,此筆資料就稱為『紀錄』(Record)。記載許多事件而必須寫入磁碟檔案時,就需要一筆紀錄接一筆,將紀錄依序寫入檔案系統,此格式則稱為『紀錄檔案』(Record file)。一般作業系統為了提高效益,並不立即將紀錄寫入檔案內,而是將紀錄資料組裝成『緩衝器』(Buffer)格式,暫存於主記憶體的某一固定空間內,等待電腦較有空閒或已累積多筆『緩衝器』資料時,再一併寫入檔案(或稱磁碟機)。由檔案讀出資料也是一樣,電腦一次由磁碟檔案裡讀出多筆『緩衝器』資料(儲存於主記憶體內),再依序由『緩衝器』讀入執行中的程式。一次讀取一筆資料模式大多運用於管理資訊系統的大量資料儲存。也就是說,一般『電子化』管理系統的資料儲存大多採用記錄檔案格式與緩衝器存取模式。

簡單的說,紀錄檔案的存取都需透過緩衝器的運作,因此宣告順序檔案物件時,也須宣告緩衝器物件,並將兩者連結起來成為『程式』的輸入/輸出檔案物件。圖 6-2 為產生紀錄檔案的宣告方式,它是屬於 java.io 套件的類別。以下分別說明輸入與輸出檔案的宣告方法。

6-2 紀錄檔案輸入/輸出物件

6-2 記錄檔案的存取介面

6-2-1 檔案寫入介面

宣告可寫入記錄檔案的命令(檔案為 Employee.data),與相關存取方法如下:(如圖 6-2)

宣告『可寫入』紀錄檔案的語法範例:

功能說明:

import java.io.*;

導入 java.io 套件

String file = “Employee.data”

檔案名稱(範例:Employee.data

FileWriter fw = new FileWriter(file);

產生可供寫入的紀錄檔案

BufferedWriter bw = new BufferedWriter(fw);

產生可供寫入的緩衝器

void bw.write()

將字元、字串或位元寫入檔案。

void bw.flush()

強迫寫入檔案。

void bw.newLine()

於檔案內開啟新行(行分隔)。

void bw.close()

關閉檔案。

重點說明如下:

6-2-2 檔案輸出介面

產生可讀取檔案與可寫入檔案的步驟大致上相同。以 Employee.data 檔案為例,產生的宣告步驟如下:(如圖 6-2 所示)

宣告『可讀取』紀錄檔案的語法範例:

功能說明:

import java.io.*;

導入 java.io 套件

String file = “Employee.data”

檔案名稱(範例:Employee.data

File fileID = new File(file);

開啟檔案,並回傳檔案識別碼

FileReader fr = new FileReader(fileID);

產生可供讀取的紀錄檔案

BufferedReader br = new BufferedReader(fr);

產生可供讀取的緩衝器

bw.read()

緩衝器讀取方法之一

重點說明如下:

檔案物件的方法:

說明:

boolean canRead()

測試檔案是否可讀取。

boolean canWrite()

測試檔案是否可寫入。

boolean exists()

測試檔案是否存在

boolean isFile()

測試是否是一般檔案。

『可讀取』檔案的方法:

說明:

void close()

關閉檔案。

void mark()

於檔案內標示某一位置。

int read()

讀取以字串或位元組格式讀取檔案。

String readLine()

由檔案讀取一行(或一筆)紀錄。

void reset()

重置檔案回標示位置。

6-3 紀錄檔案的輸出運用

6-3-1 物件陣列與記錄檔案

電子化管理系統的資料大多有固定格式,每一筆資料就成為一個紀錄。譬如,某一公司的員工管理系統,每一筆紀錄登錄一位員工的資料;也依照系統需求,每一筆資料由若干個屬性所構成。紀錄型態資料大多以一筆接一筆紀錄型態儲存於檔案內,資料系統需要處理這些資料時,再由紀錄檔案讀入主機電腦的記憶體內。然而,紀錄資料於記憶體內儲存方式又有許多格式,譬如陣列、樹狀或鏈路格式等等,即是資料結構的型態。

6-3 為紀錄檔案與陣列資料之間的存取方法。每一陣列元素是一筆紀錄資料(物件變數),其中包含了若干屬性的變數資料。陣列資料輸出到紀錄檔案是方法是,每筆資料是一個屬性接一個屬性寫入,屬性之間利用一個分隔符號(Delimit)區分,可能是『tab』(\t)空白鍵、分號(;)或單一空白鍵等等。一筆資料輸出完畢後,再跳到下一行繼續輸出,與輸出到螢幕的方法非常類似。

6-3 陣列內物件變數輸出到紀錄檔案

6-3-2 範例研討:登錄員工資料

A)程式功能:Ex6_1.java

請幫志明電器製造公司建立一套人事管理系統,該系統允許輸入員工資料,並儲存於資料檔案內(Human.data)。假設登錄員工資料包含有:員工代號(int)、姓名(String)、工作部門(String)、底薪(int)、職務加級(int)。期望操作介面,以及檔案輸出結果如下:

G:\Examples\chap9\Ex6_1>java Ex6_1

是否繼續輸入員工資料 (yes/no) =>yes

***** 輸入員工資料 *****

輸入員工姓名 =>陳中心

輸入所屬部門 =>倉管課

輸入員工代號 =>71219

輸入員工底薪 =>32000

輸入薪資加級 =>17000

是否繼續輸入員工資料 (yes/no) =>yes

***** 輸入員工資料 *****

輸入員工姓名 =>劉明新

輸入所屬部門 =>行銷課

輸入員工代號 =>71242

輸入員工底薪 =>31000

輸入薪資加級 =>15000

是否繼續輸入員工資料 (yes/no) =>no

***** 將員工資料輸出到 Human.dada 檔案內 ****

***** 輸出完畢 ****

 

G:\Examples\chap9\Ex6_1>dir/b

Employee.class

Human.data

Ex6_1.java

Ex6_1.class

 

G:\Examples\chap9\Ex6_1>type Human.data        type 顯示檔案內容命令】

71219   陳中心  倉管課  32000   17000

71242   劉明新  行銷課  31000   15000

B)製作技巧研討:

本系統製作要點是,宣告產生一個物件陣列,將連續輸入的員工資料寫入其中,輸入完畢之後,再將物件陣列內容一筆接一筆寫入輸出檔案上。須注意的是,輸出檔案上每一行存放一筆員工資料,資料的每個屬性分別由一個欄位表示。虛擬碼提示如下:

宣告物件陣列的類別(Employee.data);

主類別(Ex6_1)範圍:{

宣告產生物件陣列(Employee[] worker;);

宣告輸出檔案物件:

String file = "Human.data";

BufferedWriter data = new BufferedWriter(new FileWriter(file));

連續讀取多筆員工資料並存入物件陣列中(while() { …});

將物件陣列輸出到檔案;

}

C)程式範例:

6-4 Ex6_1 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

//Ex6_1.java

/*系統允許輸入員工資料,並儲存於資料檔案內(Human.data) */

 

import java.util.Scanner;

import java.io.*;

class Employee {      /* 物件陣列的類別宣告 */

     int ID;          // 員工代號

     String name;     // 員工姓名

     String depart;   // 所屬部門

     int payment;     // 底薪

     int duty;        // 職務加級

}

 

public class Ex6_1 {

    public static void main(String args[]) throws IOException {

        Scanner keyin = new Scanner(System.in);

        Employee[] worker = new Employee[20];

 

        /* 宣告輸出檔案物件 */

        String file = "Human.data";

        BufferedWriter data = new BufferedWriter(new FileWriter(file));

        int k=0;

        String sel;

      

        /* 讀入資料並存入物件陣列內 */

        System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

        sel = keyin.nextLine();

        while(sel.equals("yes") && (k <20)) {

            worker[k] = new Employee();

            System.out.printf("***** 輸入員工資料 *****\n");

            System.out.printf("輸入員工姓名 =>");

            worker[k].name = keyin.nextLine();

            System.out.printf("輸入所屬部門 =>");

            worker[k].depart = keyin.nextLine();

            System.out.printf("輸入員工代號 =>");

            worker[k].ID = keyin.nextInt();

            System.out.printf("輸入員工底薪 =>");

            worker[k].payment = keyin.nextInt();

            System.out.printf("輸入薪資加級 =>");

            worker[k].duty = keyin.nextInt();

            keyin.nextLine();                   // 清除鍵盤輸入

            System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

            sel = keyin.nextLine();

            k = k+1;

        }

      

        /* 將物件陣列內容寫入檔案內 */

        System.out.printf("*** 將員工資料輸出到 Human.dada 檔案內 **\n");

        for (int i=0; i<k; i++) {

            data.write(worker[i].ID + "\t");  

            data.write(worker[i].name + "\t");

            data.write(worker[i].depart + "\t");

            data.write(worker[i].payment + "\t");

            data.write(worker[i].duty + "\n");

        }

        data.close();

        System.out.printf("***** 輸出完畢 ****\n");

   }

}

D 程式重點說明:

6-3-3 自我挑戰:超商列印購物清單

A)程式功能:PM6_1.java

擴充範例 Ex5_4.java程式功能(本書第五章)。請擴充『春嬌生鮮超市』販賣系統的功能,除了可由螢幕點選客人購買商品與數量外,最後可由螢幕顯示總購買金額,並印出收據(寫入檔案)。假設僅販賣:可口餅乾(20 元)、味全鮮乳(30 元)、御便當(50 元)、黑松汽水(20 元)、頻果西打(30 元)與脆笛酥(20 元),期望操作介面如下:

D:\Java2_book\chap6\PM6_1>javac PM6_1.java

 

D:\Java2_book\chap6\PM6_1>dir/b

Element.class

List.data

PM6_1.class

PM6_1.java

D:\Java2_book\chap6\PM6_1>java PM6_1

  **** 歡迎光臨  春嬌超商 請選擇購買商品  ****

(1) 可口餅乾 20       (2) 味全鮮乳 30       (3) 御便當 50

(4) 黑松汽水 20       (5) 頻果西打 30       (6) 脆笛酥 20

(7) 結算金額

        請輸入選項 =>1

        購買數量 =>24

  **** 歡迎光臨  春嬌超商 請選擇購買商品  ****

(1) 可口餅乾 20       (2) 味全鮮乳 30       (3) 御便當 50

(4) 黑松汽水 20       (5) 頻果西打 30       (6) 脆笛酥 20

(7) 結算金額

        請輸入選項 =>3

        購買數量 =>15

  **** 歡迎光臨  春嬌超商 請選擇購買商品  ****

(1) 可口餅乾 20       (2) 味全鮮乳 30       (3) 御便當 50

(4) 黑松汽水 20       (5) 頻果西打 30       (6) 脆笛酥 20

(7) 結算金額

        請輸入選項 =>5

        購買數量 =>8

  **** 歡迎光臨  春嬌超商 請選擇購買商品  ****

(1) 可口餅乾 20       (2) 味全鮮乳 30       (3) 御便當 50

(4) 黑松汽水 20       (5) 頻果西打 30       (6) 脆笛酥 20

(7) 結算金額

        請輸入選項 =>7

總購買金額 = 1470

 

** 採購清單列印中 (List.data) **

** 列印完畢 (List.data) **

 

G:\Examples\chap9\PM9_1>type List.data    type顯示檔案內容命令】

== 春嬌超商 購物清單 歡迎再度光臨 ==

品名            單價    數量     小計

-----------------------------------------------------

可口餅乾        20      24      480

御便當          50      15      750

頻果西打        30      8       240

總購買金額 = 1470 元整

B)製作技巧提示:

6-5 PM6_1 程式架構

吾人僅修改 Ex5_4.java 範例即可,原來購物清單是由螢幕顯示,將轉換到檔案輸出即可,虛擬碼提示如下:

/* Ex5_4.java 程式內容 */

….

宣告產生檔案輸出物件:

String file = "List.data";

BufferedWriter data = new BufferedWriter(new FileWriter(file));

…..

將物件陣列內容輸出到檔案內:

data.write("== 春嬌超商 購物清單 歡迎再度光臨 ==\n");

data.write("品名\t\t單價 \t數量\t 小計\n");

data.write("------------------------------------\n");

for (int i=0; i<k; i++) {

data.write(cust[i].name + "\t");  

data.write(cust[i].price + "\t");

data.write(cust[i].pice + "\t");

data.write(cust[i].sum + "\n");

}

data.write("總購買金額 = "+total+" 元整");

data.close();

/* Ex5_4.java 程式內容 */

…..

 

6-4 紀錄檔案的輸入/輸出運用

6-4-1 記錄檔案輸出格式

讀取紀錄檔案大多是每次讀取一筆資料,即是每次讀取檔案內的一行資料,而不論每行包含多少屬性資料。各個屬性都有自己的資料型態,因此讀取時,只好將該筆資料可為一個字串(String)。圖 6-4 是讀取紀錄檔案的基本運作模式。每次讀取一筆資料並以字串格式儲存於 inData 變數內,亦可直接輸出到螢幕上。(如何轉換成陣列變數資料,下一個範例再說明,Ex6_2_1.java

6-4 紀錄檔案整筆輸入,並整筆輸出螢幕顯示

6-4-2 範例研討:建立員工薪資資料

A)程式功能:Ex6_2.java

擴充 Ex6_1.java 程式功能。請幫志明電器製造公司建立一套人事管理系統,該系統允許輸入員工資料,並儲存於資料檔案內(Human.data)。當輸入完畢之後,再由檔案內讀出並顯示螢幕上,觀察資料是否建立正確。假設登錄員工資料包含有:員工代號(int)、姓名(String)、工作部門(String)、底薪(int)、職務加級(int);期望操作介面,以及檔案輸出結果如下:

G:\Examples\chap9\Ex6_2>java Ex6_2

是否繼續輸入員工資料 (yes/no) =>yes

***** 輸入員工資料 *****

輸入員工姓名 =>張志明

輸入所屬部門 =>製造課

輸入員工代號 =>71209

輸入員工底薪 =>40000

輸入薪資加級 =>15000

是否繼續輸入員工資料 (yes/no) =>yes

……

……

是否繼續輸入員工資料 (yes/no) =>no

** 將資料輸出到 Human.dada 檔案內 **

***** 輸出完畢 ****

 

== Human.data 讀取並顯示 ==

代號    姓名    部門    底薪    加級

71209   張志明  製造課  40000   15000

71210   羅大仙  製造課  43000   16800

71214   陳名郎  生管課  28000   12000

71219   蔡中心  倉管課  32000   17000

71242   劉新明  行銷課  28000   15000

== Human.data 輸入完畢 ==

B)製作技巧研討:

本系統包含檔案(Human.data)輸出與輸入處理,其運作情形如圖 6-5 所示。也針對檔案輸出與輸入,分別產生下列兩個

物件,及其方法如下所示:

檔案名稱

String file = “Human.data”;

輸出物件

BufferedWriter data = new BufferedWriter(new FileWriter(file));

寫入方法

data.write()

關閉方法

dada.close()

輸入物件

BufferedReader data_R = new BufferedReader(new FileReader(fileID));

讀取方法

data_R.read()

關閉方法

data_R.cloas()

  6-5 範例 Ex6_2 程式架構

Ex6_2 程式運作如下:程式開始時宣告產生鍵盤(標示 (1))與輸出檔案物件(標示 (2)),以及一只儲存資料的物件陣列,接著利用 while 迴圈連續讀取多筆資料,系統也隨時存入物件陣列內。操作者輸入完畢之後後,則將物件陣列內容,一筆接一筆寫入檔案(data.write(),標示 (2))。輸出完畢後,系統再由檔案讀出(data_R.read(),標示 (3)),也一筆接一筆顯示到螢幕上(標示 (4))。

C)程式範例:

6-8 Ex6_2 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

//Ex6_2.java

/* 擴充Ex6_1程式功能,將輸出的結果寫入檔案 */

 

import java.util.Scanner;

import java.io.*;

class Employee {      /* 物件陣列的類別宣告 */

     int ID;          // 員工代號

     String name;     // 員工姓名

     String depart;   // 所屬部門

     int payment;     // 底薪

     int duty;        // 職務加級

}

 

public class Ex6_2 {

    public static void main(String args[]) throws IOException {

        Scanner keyin = new Scanner(System.in);

        Employee[] worker = new Employee[20];

 

        /* 宣告輸出檔案物件 */

        String file = "Human.data";

        BufferedWriter data = new BufferedWriter(new FileWriter(file));

        int k=0;

        String sel;

      

        /* 讀入資料並存入物件陣列內 */

        System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

        sel = keyin.nextLine();

        while(sel.equals("yes") && (k <20)) {

            worker[k] = new Employee();

            System.out.printf("***** 輸入員工資料 *****\n");

            System.out.printf("輸入員工姓名 =>");

            worker[k].name = keyin.nextLine();

            System.out.printf("輸入所屬部門 =>");

            worker[k].depart = keyin.nextLine();

            System.out.printf("輸入員工代號 =>");

            worker[k].ID = keyin.nextInt();

            System.out.printf("輸入員工底薪 =>");

            worker[k].payment = keyin.nextInt();

            System.out.printf("輸入薪資加級 =>");

            worker[k].duty = keyin.nextInt();

            keyin.nextLine();                 //清除鍵盤緩衝器

            System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

            sel = keyin.nextLine();

            k = k+1;

        }

      

        /* 將物件陣列內容寫入檔案內 */

        System.out.printf("** 將資料輸出到 Human.dada 檔案內 **\n");

        for (int i=0; i<k; i++) {

            data.write(worker[i].ID + "\t");  

            data.write(worker[i].name + "\t");

            data.write(worker[i].depart + "\t");

            data.write(worker[i].payment + "\t");

            data.write(worker[i].duty + "\n");

        }

        data.close();

        System.out.printf("***** 輸出完畢 ****\n");

 

        /* 檔案輸出程式, 每次讀取一筆資料 */

        System.out.printf("\n== Human.data 讀取並顯示 ==\n");

        String inData;

        File fileID = new File(file);         //開啟 Human.data 檔案

        if (fileID.exists()) {

          BufferedReader data_R = new BufferedReader(new FileReader(fileID));

            System.out.print("代號\t姓名\t部門\t底薪\t加級\n");

            while ((inData=data_R.readLine()) != null)

                System.out.printf("%s\n", inData);

            data_R.close();

        }

        else

           System.out.printf("%s 檔案讀取錯誤\n", file);

        System.out.printf("== Human.data 輸入完畢 ==\n");

   }

}

D)程式重點說明:

G:\Examples>copy con: Human.data

^Z

複製了         1 個檔案。

6-4-3 自我挑戰:列印員工薪資表

A)程式功能:PM6_2.javaEmployee.class

志明電器公司已建立完成員工薪資管理系統(Ex6_2.java),該系統允許管理者輸入員工薪資資料,並可除儲存於 Human.data 檔案內。請編寫一套程式可供列印公司所有員工的薪資表,員工資料直接由 Human.data 檔案讀取。薪資表包含員工代號、姓名、服務部門,薪資總額(= 底薪 + 職務加級)、預扣稅額(= 薪資總額 * 0.1)與應領薪資(薪資總額預扣稅額);期望操作如下:

D:\Java2_book\chap6\PM6_2>javac PM6_2.java

 

D:\Java2_book\chap6\PM6_2>dir/b

Employee.class

Human.data

PM6_2.class

 

D:\Java2_book\chap6\PM6_2>java PM6_2

== 志明電器公司  員工薪資表 ==

員工資料                薪資總額    預扣稅額  應領薪資

張志明(71209 製造課)    55000           5500    49500

羅大仙(71210 製造課)    59800           5980    53820

陳名郎(71214 生管課)    40000           4000    36000

蔡中心(71219 倉管課)    49000           4900    44100

劉新明(71242 行銷課)    43000           4300    38700

 

薪資總額 = 246800 元整  總稅額 = 24680 元整  總應額 = 222120 元整

B)製作技巧研討:

本範例最大的特點是,每筆資料由檔案讀入後,如何儲存於物件陣列內,處理方式如圖 6-6 所示。首先系統利用 readLine() 方法讀入整筆資料後儲存於 inData 變數內,該資料還是屬於字串格式(String)。接著將 inData 導入 Scanner 類別,宣告其物件(data_R),其中必須設定字串資料之中各個欄位的『分界符號』(Demiliter),再利用 Scanner 物件方法,分別讀取各欄位資料再寫入陣列物件的變數成員內。相關之物件及其方法如下:

範例:

說明:

inData=data.readLine()

由檔案讀取一筆資料。

Scanner s = new Scanner(inData).useDelimiter("\t");

宣告成 Scanner 物件並設定分界符號(\t),物件名稱為 s

worker[k].ID = s.nextInt();

讀取一整數,再存入陣列物件的變數成員內。

6-6 紀錄檔案讀入,每筆儲存於物件陣列內

C)程式片段:

6-10 PM6_2 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

//PM6_2.java, Human.data 檔案需存在

/* Employee.class 需存在於同目錄下 */

import java.io.*;

import java.util.Scanner;

public class PM6_2 {

    public static void main(String args[]) throws IOException {

         Employee[] worker = new Employee[20];

         String file = "Human.data";

         String inData;

         int k=0;

         File fileID = new File(file);

         if (fileID.exists()) {

 

            /* Humam.data 讀取員工資料並存入 worker[] 陣列 */

            BufferedReader data = new BufferedReader(new

 FileReader(fileID));

            while ((inData=data.readLine()) != null) {

                 Scanner s = new Scanner(inData).useDelimiter("\t");

                 worker[k] = new Employee();

                 worker[k].ID = s.nextInt();

                 worker[k].name = s.next();

                 worker[k].depart = s.next();

                 worker[k].payment = s.nextInt();

                 worker[k].duty = s.nextInt();

                 k = k +1;

            }

            data.close();

 

            /* 計算並列印薪資表 */

            System.out.printf("== 志明電器公司  員工薪資表 ==\n");

            System.out.print("員工資料\t\t薪資總額\t預扣稅\t應領薪資\n");

            ……

            ……

       else

           System.out.printf("%s 檔案不存在\n", file);

   }

}

D)程式重點分析:

 

6-5 專題製作

6-5-1 範例研討:建立人事管理資訊系統

A)程式功能:Ex6_3.javaPersonal.java

『展鵬網路行銷公司』希望建立一個電子化管理系統,其中包含若干個子系統,各子系統所使用的員工資料都能夠統一處理,才不至於發生各系統之間不一致的問題。請您幫該公司規劃員工資料的屬性,並建立『人事資料管理系統』(Ex6_3.java)可讓管理人員『新增』、『修改』與『刪除』員工資料,爾後其他子系統也可引用該資料(Human.data)。目前預估員工資料包含有:員工代號、姓名、服務部門、性別、出生、底薪、職務加級等屬性,並由獨立檔案製作而成(Persional.java),經過編譯後產生 Persional.class。至於員工資料請以 Human.data 檔案名稱儲存。期望操作介面與執行結果如下:

D:\Java2_book\chap6\Ex6_3>java Ex6_3

Human.data 檔案不存在, 請先建立它

<enter>鍵離開 =>

D:\Java2_book\chap6\Ex6_3>java Ex6_3

=== 人事資料管理系統 ===

(1) 顯示所有資料        (2) 增加員工資料        (3) 修改員工資料

(4) 刪除員工資料        (5)           (6)  

請選擇工作項目 =>

請選擇工作項目 => 1

= 列印所有員工資料 ==

代號    姓名    部門    性別    出生    底薪    加級

101    王力宏  會計課        63/12/5 80000   40000

102    張惠妹  業務課        64/3/12 90000   70000

103    蔡依玲  製造課        67/3/15 80000   60000

請選擇工作項目 => 2

請輸入員工編號 =>7106

請輸入姓名 =>劉有得

請輸入服務部門 =>資訊部

請輸入性別 (/) =>

請輸入生日 (西元//) =>71/09/12

請輸入底薪 =>54000

請輸入職務加級 =>11000

請選擇工作項目 => 3

請輸入欲修改員工的代號 =>7105

請輸入 張有德 姓名 =>張有得

請輸入 資訊部 服務部門 =>製造部

請輸入性別 (/) =>

請輸入生日 75/09/23 (//) =>76/09/23

請輸入 60000 底薪 =>50000

請輸入 20000 職務加級 =>20000

請選擇工作項目 => 4

請輸入欲刪除員工的代號 =>7105

7105 資料已刪除 !!

請選擇工作項目 => 5

** 將儲存檔案 (Human.dada) **

***** 儲存完畢 ****

B)製作技巧研討:

吾人將製作本系統的重點歸類成下列重點: (如圖 6-7 所示)

6-11 人事資料管理系統架構

C)程式範例:(執行前,須建立 Human.data 檔案)

6_12 Ex6_3 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

//Personal.java

 

class Personal {     

     int ID;          // 員工代號

     String name;     // 員工姓名

     String depart;   // 服務部門

     String sex;      //    

     String birth;    // 出生日期

     int payment;     //    

     int duty;        // 職務加級

}

 

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

//Ex6_3.java

/* 請建立一套人事資料管理系統,可讓管理人員新增、修改、刪除員工資料 */

 

import java.io.*;

import java.util.Scanner;

public class Ex6_3 {

    static Personal[] emp;         // 員工資料的物件陣列

    static int k;                  // 紀錄儲存筆數

    static Scanner keyin;   // 鍵盤輸入物件

 

    public static void main(String args[]) throws IOException {

       keyin = new Scanner(System.in);

 

       /* 讀取 Human.data 檔案資料, 再存入 emp 物件陣列中 */

       emp = new Personal[50];

       k=0;         // 讀取資料的筆數

       String inData;

       String file_R = "Human.data";                    

       File fileID = new File(file_R);    // 產生輸入檔案物件

       if (fileID.exists()) {

           BufferedReader data = new BufferedReader(new

                                              FileReader(fileID));

           while ((inData=data.readLine()) != null) {

                Scanner s = new Scanner(inData).useDelimiter("\t");

                emp[k] = new Personal();

                emp[k].ID = s.nextInt();

                emp[k].name = s.next();

                emp[k].depart = s.next();

                emp[k].sex = s.next();

                emp[k].birth = s.next();

                emp[k].payment = s.nextInt();

                emp[k].duty = s.nextInt();

                k = k +1;

           }

           data.close();

       }

       else {

           System.out.printf("%s 檔案不存在, 請先建立它\n", file_R);

           System.out.printf("按任何鍵離開 =>");

           keyin.nextLine();

           System.exit(1);

       }

       mainMenu();

       int select = keyin.nextInt();

       while (select !=6) {

            switch (select) {

                case 1:     /* 顯示員工資料 */

                     disp_data();

                     break;

                case 2:     /* 增加員工資料 */

                     add_data();

                     break;

                case 3:     /* 修改員工資料 */

                     modify_data();

                     break;

                case 4:          /* 刪除資料 */

                     delete_data();

                     break;

                case 5:          /* 儲存資料 */

                     save_data();

                     break;

                default:

                     System.out.printf("錯誤輸入, 請重新選擇 !!\n");

           }

           mainMenu();

           select = keyin.nextInt();

       }

    }

    public static void mainMenu() {

        System.out.printf("\n=== 人事資料管理系統 ===\n");

        System.out.printf("(1) 顯示所有資料\t");

        System.out.printf("(2) 增加員工資料\t");

        System.out.printf("(3) 修改員工資料\n");

        System.out.printf("(4) 刪除員工資料\t");

        System.out.printf("(5)   \t");

        System.out.printf("(6)   \n");

        System.out.printf("請選擇工作項目 => ");

    }

    public static void disp_data() {

        System.out.printf("== 列印所有員工資料 ==\n");

        System.out.printf("代號\t姓名\t部門\t性別\t出生\t底薪\t加級\n");

        for (int i=0; i<k; i++) {

            System.out.printf("%d\t", emp[i].ID);

            System.out.printf("%s\t", emp[i].name);

            System.out.printf("%s\t", emp[i].depart);

            System.out.printf("%s\t", emp[i].sex);

            System.out.printf("%s\t", emp[i].birth);

            System.out.printf("%d\t", emp[i].payment);

            System.out.printf("%d\n", emp[i].duty);

        }

    }

    public static void add_data() throws IOException {

          emp[k] = new Personal();

          System.out.printf("請輸入員工編號 =>");

             emp[k].ID = keyin.nextInt();

             keyin.nextLine();          //清除鍵盤緩衝器

          System.out.printf("請輸入姓名 =>");

             emp[k].name = keyin.nextLine();

          System.out.printf("請輸入服務部門 =>");

             emp[k].depart = keyin.nextLine();

          System.out.printf("請輸入性別 (/) =>");

             emp[k].sex = keyin.nextLine();

          System.out.printf("請輸入生日 (//) =>");

             emp[k].birth = keyin.nextLine();

          System.out.printf("請輸入底薪 =>");

             emp[k].payment = keyin.nextInt();

          System.out.printf("請輸入職務加級 =>");

             emp[k].duty = keyin.nextInt();

          k = k+1;

     }

     public static void modify_data() throws IOException {

          System.out.printf("請輸入欲修改員工的代號 =>");

          int num = keyin.nextInt();

          keyin.nextLine();          //清除鍵盤緩衝器

          int flag = 0;

          int i = 0;

          while(i < k) {

              if (emp[i].ID == num) {

                  flag = 1;

                  break;

              }

              i = i + 1;

          }

          if (flag == 0) {

             System.out.printf("test here 5\n");

             System.out.printf("沒有 %d 資料, 拒絕處理 !!\n", num);

             return;

          }         

          System.out.printf("請輸入 %s 姓名 =>", emp[i].name);

             emp[i].name = keyin.nextLine();

          System.out.printf("請輸入 %s 服務部門 =>", emp[i].depart);

             emp[i].depart = keyin.nextLine();

          System.out.printf("請輸入性別 %s (/) =>", emp[i].sex);

             emp[i].sex = keyin.nextLine();

          System.out.printf("請輸入生日 %s (//) =>", emp[i].birth);

             emp[i].birth = keyin.nextLine();

          System.out.printf("請輸入 %d 底薪 =>", emp[i].payment);

             emp[i].payment = keyin.nextInt();

          System.out.printf("請輸入 %d 職務加級 =>", emp[i].duty);

             emp[i].duty = keyin.nextInt();

     }

     public static void delete_data() throws IOException {

          System.out.printf("請輸入欲刪除員工的代號 =>");

          int num = keyin.nextInt();

          int flag = 0, m = 0;

          while(m < k) {

              if (emp[m].ID == num){

                  flag = 1;

                  break;

              }

              m = m + 1;

          }

          if (flag == 0){

             System.out.printf("沒有 %d 資料, 拒絕處理 !!\n", num);

             return;

          }

          for(int i=m; i<k; i++)

              emp[i]=emp[i+1];

          k = k-1;

          System.out.printf("%d 資料已刪除 !!\n", num);

     }

     public static void save_data() throws IOException {

         String file = "Human.data";

         BufferedWriter outData = new BufferedWriter(new FileWriter(file));

         System.out.printf("** 將儲存檔案 (Human.dada) **\n");

         for (int i=0; i<k; i++) {

             outData.write(emp[i].ID + "\t");  

             outData.write(emp[i].name + "\t");

             outData.write(emp[i].depart + "\t");

             outData.write(emp[i].sex + "\t");

             outData.write(emp[i].birth + "\t");

             outData.write(emp[i].payment + "\t");

             outData.write(emp[i].duty + "\n");

        }

        outData.close();

        System.out.printf("***** 儲存完畢 ****\n");

    }

}

D)程式重點分析:

 

6-5-2 自我挑戰:超商商品管理系統

A)程式功能:PM6_3.javaElement.java

請幫『春嬌生鮮超市』建立一套商品登錄系統。該系統功能有『顯示所有資料』、『增加商品資料』、以及『儲存資料』。庫存資料儲存於 storage.data 檔案內。假設描述商品屬性(Element.java)為:商品編號(String no)、商品名稱(String name)、單價(int price)、單位(Sting unit)、庫存量(int stock)與製造商(String maker)。期望操作介面與結果如下:

D:\Java2_book\chap6\PM6_3>java PM6_3

storage.data 檔案不存在, 請先建立它

<Enter> 鍵離開 =>

D:\Java2_book\chap6\PM6_3>java PM6_3

 

== 春嬌超市 商品管理系統 ==

(1) 顯示所有資料        (2) 增加商品資料        (3) 修改商品資料

(4)           (5)  

請選擇工作項目 =>

D:\Java2_book\chap6\PM6_3>java PM6_3

 

== 春嬌超市 商品管理系統 ==

(1) 顯示所有資料        (2) 增加商品資料        (3) 修改商品資料

(4)           (5)  

請選擇工作項目 =>

請選擇工作項目 => 1

== 列印所有商品資料 ==

代號    品名            單價    單位    庫存量        製造商

A1001   黑松汽水        20            210             黑松公司

A1002   可口奶滋        50            310             統一食品

請選擇工作項目 => 2

請輸入商品編號 =>1005

請輸入商品名稱 =>台灣啤酒

請輸入單價 =>60

請輸入單位 (//公斤) =>

請輸入安全庫存量 =>50

請輸入製造商 =>台灣菸酒公司

請選擇工作項目 => 3

請輸入欲修改的商品編碼 =>A1005

[台灣啤酒]請輸入商品名稱 =>金門高粱

[60]請輸入單價 =>500

[]請輸入單位 (//公斤) =>

[50]請輸入庫存量 =>30

[台灣菸酒公司]請輸入製造商 =>金門酒廠

請選擇工作項目 => 4

** 將儲存檔案 (storage.data) **

***** 儲存完畢 ****

B)製作技巧提示:

為了方便製作,吾人可將此系統劃分為若干個子系統(方法或函數)來分別實現,如圖 6-8 所示;虛擬碼提示如下:

6-8 超商商品管理系統架構

宣告商品類別(class Element { …};

宣告主類別範圍(class PM9_2{

宣告商品物件陣列(static Element[] art);

宣告紀錄資料筆數的變數(static int number);

宣告庫存檔案的變數(static String file);

宣告鍵盤輸入物件(static BufferedReader keyin);

宣告主方法範圍(main(){

產生物件陣列範圍(art = new Element[50]);

設定類別變數內容(number=0file=”storage.data);

呼叫執行讀取檔案資料方法(read_data());

呼叫主功能選單(mainMenu())並讀取功能選項(select;

while (select != 4) {

switch(select) {

case 1: disp_data()  /* 顯示所有資料 */

case 2: add_data()   /* 增加商品資料 */

case 3: modify_data()   /* 修改商品資料 */

case 4: save_data()   /* 儲存資料 */

}

   呼叫主功能選單(mainMenu())並讀取功能選項(select;

}

    } // 主方法結束

    /* 主工作項目選單 */

宣告主功能表選單方法(mainMenu() { ….});

宣告檔案讀取方法(read_data());

/* stroage.data 檔案讀入並存入 art[] 陣列 */

    宣告顯示所有資料方法(disp_data());

宣告增加商品資料方法(add_data());

    宣告儲存商品資料方法(save_data());

/* art[] 陣列內容輸出至 storage.data 檔案 */

} // 主類別結束

(C) 程式片段提示

6-15 PM6_3 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

//Element.java

 

class Element {

    String ID;        // 商品編號

    String name;      // 商品名稱

    int price;        // 單價

    String unit;      // 單位

    int stock;        // 庫存數量

    String maker;     // 製造商

}

 

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

//PM6_3.java

/* 請建立一套商品登錄系統,功能有:顯示所有資料、增加商品資料、儲存資料;

 * 資料儲存於storage.data檔案內 */

 

/* Element.class 須於同目錄下 */

import java.io.*;

import java.util.Scanner;

public class PM6_3 {

    static Element[] art;            // 商品資料的物件陣列

    static int number;               // 紀錄儲存筆數

    static Scanner keyin;     // 鍵盤輸入物件

    static String file_R;    // 庫存檔案

 

    public static void main(String args[]) throws IOException {

       keyin = new Scanner(System.in);

 

       art = new Element[50];

       number=0;                 // 儲存資料的筆數

       file_R = "storage.data";                  

       read_data();

 

       mainMenu();

       int select = keyin.nextInt();

       keyin.nextLine();

       while (select !=5) {

            switch (select) {

                case 1:     /* 顯示所有資料 */

                     disp_data();

                     break;

                case 2:     /* 增加商品資料 */

                     add_data();

                     break;

                case 3:     /* 修改商品資料 */

                     modify_data();

                     break;

                case 4:          /* 儲存資料 */

                     save_data();

                     break;

                default:

                     System.out.printf("錯誤輸入, 請重新選擇 !!\n");

           }

           mainMenu();

           select = keyin.nextInt();

           keyin.nextLine();

       }

    }

    /* 主工作項目選單 */

    public static void mainMenu() {

        System.out.printf("\n== 春嬌超市 商品管理系統 ==\n");

        …..

        ….

 

    }

 

    /* stroage.data 檔案輸入至系統 */

    public static void read_data() throws IOException {

        File fileID = new File(file_R);    // 產生輸入檔案物件

        String inData;

        if (fileID.exists()) {

            BufferedReader data = new BufferedReader(new

                                              FileReader(fileID));

            while ((inData=data.readLine()) != null) {

                Scanner s = new Scanner(inData).useDelimiter("\t");

                art[number] = new Element();

                art[number].ID = s.next();

                art[number].name = s.next();

                art[number].price = s.nextInt();

                art[number].unit = s.next();

                art[number].stock = s.nextInt();

                art[number].maker = s.next();

                number = number +1;

           }

           data.close();

       }

       else {

           System.out.printf("%s 檔案不存在, 請先建立它 \n", file_R);

           System.out.printf(" <Enter> 鍵離開 =>");

           keyin.nextLine();

           System.exit(1);

       }

    }

 

    /* 顯示所有資料 */

    public static void disp_data() {

        System.out.printf("== 列印所有商品資料 ==\n");

        System.out.printf("代號\t品名\t\t單價\t單位\t安全庫存量\t製造商\n");

        for (int i=0; i<number; i++) {

            System.out.printf("%s\t", art[i].ID);

            System.out.printf("%4s\t", art[i].name);

            System.out.printf("%d\t", art[i].price);

            System.out.printf("%s\t", art[i].unit);

            System.out.printf("%d\t\t", art[i].stock);

            System.out.printf("%s\n", art[i].maker);

        }

    }

 

    /* 增加商品資料 */

    public static void add_data(){

          int k=number;

          art[k] = new Element();

          System.out.printf("請輸入商品編號 =>");

             art[k].ID = keyin.nextLine();

          System.out.printf("請輸入商品名稱 =>");

             art[k].name = keyin.nextLine();

          System.out.printf("請輸入單價 =>");

             art[k].price = keyin.nextInt();

             keyin.nextLine();

          System.out.printf("請輸入單位 (//公斤) =>");

             art[k].unit = keyin.nextLine();

          System.out.printf("請輸入庫存量 =>");

             art[k].stock = keyin.nextInt();

             keyin.nextLine();

          System.out.printf("請輸入製造商 =>");

             art[k].maker = keyin.nextLine();

          number = number+1;

     }

 

    /* 修改商品資料 */

    public static void modify_data(){

          System.out.printf("請輸入欲修改的商品編碼 =>");

          String num = keyin.nextLine();

          int flag = 0, test;

          int i = 0;

          while(i < number) {

              test = art[i].ID.compareTo(num);

              if (test == 0) {

                  flag = 1;

                  break;

              }

              i = i + 1;

          }

          if (flag == 0) {

             System.out.printf("沒有 %s 資料, 拒絕處理 !!\n", num);

             return;

          }         

          System.out.printf("[%s]請輸入商品名稱 =>", art[i].name);

             art[i].name = keyin.nextLine();

          System.out.printf("[%d]請輸入單價 =>", art[i].price);

             art[i].price = keyin.nextInt();

             keyin.nextLine();

          System.out.printf("[%s]請輸入單位 (//公斤) =>", art[i].unit);

             art[i].unit = keyin.nextLine();

          System.out.printf("[%d]請輸入庫存量 =>", art[i].stock);

             art[i].stock = keyin.nextInt();

             keyin.nextLine();

          System.out.printf("[%s]請輸入製造商 =>", art[i].maker);

             art[i].maker = keyin.nextLine();

     }

 

     /* 儲存商品資料至 storage.data */

     public static void save_data() throws IOException {

         BufferedWriter outData = new BufferedWriter(new FileWriter(file_R));

         System.out.printf("** 將儲存檔案 (storage.data) **\n");

         for (int i=0; i<number; i++) {

             outData.write(art[i].ID + "\t");  

             outData.write(art[i].name + "\t");

             outData.write(art[i].price + "\t");

             outData.write(art[i].unit + "\t");

             outData.write(art[i].stock + "\t");

             outData.write(art[i].maker + "\n");

        }

        outData.close();

        System.out.printf("***** 儲存完畢 ****\n");

    }

}

 

6-5-3 自我挑戰:倉儲管理系統

A)程式功能:PM6_4

(擴充 PM6_3.java 功能)請幫『春嬌超商連鎖店』建立一套『倉儲管理系統』,可供隨時登錄各連鎖店進出貨量。該系統功能有『顯示所有資料』、『增加商品資料』、『出貨登錄』、『進貨登錄』、以及『儲存資料』。庫存資料儲存於 storage.data 檔案內。當點選『出貨』或『進貨』功能時,系統會將目前所建立的商品資料顯示於螢幕上,管理者點選產品再輸入數量即可。假設描述商品屬性(article.class)為:商品編號(String no)、商品名稱(String name)、單價(int price)、單位(Sting unit)、庫存量(int stock)與製造商(String maker)。

D:\Java2_book\chap6\PM6_4>javac PM6_4.java

 

D:\Java2_book\chap6\PM6_4>java PM6_4

 

== 春嬌超市 商品管理系統 ==

(1) 顯示所有資料        (2) 增加商品資料        (3) 修改商品資料

(4) 進貨資料登錄        (5) 出貨資料登錄        (6)  

(7)  

        請選擇工作項目 =>

       請選擇工作項目 => 4

=== 請點選 (進出貨) 商品 ==

(1) 黑松汽水 260  (2) 可口奶滋 410  (3) 可口可樂 500  (4) 台灣啤酒 200

(5) 滿漢大餐 200

請輸入商品選項 =>4

進貨數量 =>50

 

= 春嬌超市 商品管理系統 ==

1) 顯示所有資料        (2) 增加商品資料        (3) 修改商品資料

4) 進貨資料登錄        (5) 出貨資料登錄        (6)  

7)  

       請選擇工作項目 => 1

= 列印所有商品資料 ==

代號    品名            單價    單位    安全庫存量      製造商

1001   黑松汽水        20            260             黑松公司

1002   可口奶滋        50            410             統一食品

1003   可口可樂        15            500             英商太古

1004   台灣啤酒        60            250             台灣菸酒

1005   滿漢大餐        50            200             統一食品

        請選擇工作項目 => 5

 === 請點選 (進出貨) 商品 ==

(1) 黑松汽水 260  (2) 可口奶滋 410  (3) 可口可樂 500  (4) 台灣啤酒 250

(5) 滿漢大餐 200

請輸入商品選項 =>3

出貨數量 =>200

 

== 春嬌超市 商品管理系統 ==

(1) 顯示所有資料        (2) 增加商品資料        (3) 修改商品資料

(4) 進貨資料登錄        (5) 出貨資料登錄        (6)  

(7)  

        請選擇工作項目 => 1

== 列印所有商品資料 ==

代號    品名            單價    單位    安全庫存量      製造商

A1001   黑松汽水        20            260             黑松公司

A1002   可口奶滋        50            410             統一食品

A1003   可口可樂        15            300             英商太古

A1004   台灣啤酒        60            250             台灣菸酒

A1005   滿漢大餐        50            200             統一食品

        請選擇工作項目 => 6

** 將儲存檔案 (storage.data) **

***** 儲存完畢 ****

B)製作技巧提示:

6-16 PM6_4 程式架構

本系統大致上與 PM6_3.java 相似,僅增加了『進貨登錄』與『出貨登錄』功能選項。當執行這兩項功能時,系統必須將目前已登錄產品與數量,顯示於螢幕上;操作者點選後,再輸入進出貨數量。因此,必須另製作一只顯示產品名稱與數量,並可選擇輸入的子程式(list_art()),兩功能子程式(enter_date() out_data())分別呼叫它,再傳回正確的產品選項。這三個子程式提示如下:

/* 進貨登錄子程式 */

public static void enter_data(){

int num = list_art();

if (num == 999) {

return;

}

System.out.printf("進貨數量 =>");

int enter = keyin.nextInt();

keyin.nextLine();

art[num].stock = art[num].stock + enter;

}

/* 出貨登錄子程式 */

public static void out_data(){

int num = list_art();

if (num == 999) {

return;

}

System.out.printf("出貨數量 =>");

int outer = keyin.nextInt();

keyin.nextLine();

art[num].stock = art[num].stock - outer;

}

 

/* 顯示商品清單及選擇商品子程式 */

public static int list_art()  {

System.out.printf(" === 請點選 (進出貨) 商品 ==\n");

for (int i=0; i<number; i++) {

System.out.printf("(%d) %s %d  ", i+1, art[i].name, art[i].stock);

if ((i+1) % 4 == 0)

System.out.printf("\n");

}

System.out.printf("\n請輸入商品選項 =>");

int num = keyin.nextInt();

keyin.nextLine();

num = num -1;

if ((num >= number) || (num < 0) ){

System.out.printf("錯誤輸入!! 按任何鍵回主選單\n");

keyin.readLine();

return 999;

}

return num;

}